<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { arr2Tree, deepClone } from '@/utils'
import { findRoles, insertRole, updateRole, deleteRole, findMenus } from '@/api/permission'
import { ElMessage } from 'element-plus'
import SytTable from '@/components/SytTable/SytTable.vue'

const tableThs = ref([
  { title: '角色名', dataIndex: 'name' },
  { title: '菜单', dataIndex: 'menusNames' }
])
let menusData = ref([])
let rolesTreeData = ref([])
let loading = ref(true)

let dialogFormVisible = ref(false)
let ruleFormRef = ref(null)
let dialogOpenType = ref('')
const rules = ref({
  name: [
    {
      required: true,
      message: '请输入角色名',
      trigger: 'blur'
    }
  ],
  menus: [
    {
      required: true,
      message: '请选择菜单',
      trigger: 'change'
    }
  ]
})

//dialog data
let rawDialogData = () => ({
  name: '',
  pid: '',
  menus: []
})

let dialogData = ref(rawDialogData())

const menusTreeData = ref([])
const getMenusTreeData = async () => {
  await findMenus().then((res) => {
    if (res.code === 200) {
      menusData.value = res.data
      menusTreeData.value = arr2Tree(res.data)
    }
  })
}
const getRolesTreeData = async () => {
  await findRoles().then((res) => {
    if (res.code === 200) {
      res.data.forEach((role) => {
        role.menusNames = role.menus.map((menuId) => {
          return menusData.value.find((menu) => menuId == menu.id)?.meta?.title
        })
      })
      rolesTreeData.value = arr2Tree(res.data)
    }
  })
}
const initData = async () => {
  await getMenusTreeData()
  await getRolesTreeData()

  loading.value = false
}

const openDialogByInsert = () => {
  dialogOpenType.value = '添加'
  dialogFormVisible.value = true

  dialogData.value = rawDialogData()
}

const openDialogByEdit = (row) => {
  dialogOpenType.value = '编辑'
  dialogFormVisible.value = true
  dialogData.value = deepClone(row)
}

const addRole = async () => {
  let data = Object.assign({}, dialogData.value)
  insertRole(data).then((res) => {
    if (res.code == 200) {
      ElMessage({ type: 'success', message: '添加成功' })
      initData()
    }
  })
}
const setRole = async () => {
  let data: any = Object.assign({}, dialogData.value)
  updateRole(data).then((res) => {
    if (res.code == 200) {
      ElMessage({ type: 'success', message: '编辑成功' })
      initData()
    }
  })
}

const removeRole = (row) => {
  if (row.id) {
    deleteRole({ id: row.id }).then((res) => {
      if (res.code == 200) {
        ElMessage({ type: 'success', message: '删除成功' })
        initData()
      }
    })
  } else ElMessage({ type: 'error', message: '不存在的id' })
}

const submitForm = (formEl) => {
  if (!formEl) return
  formEl.validate((valid) => {
    if (valid) {
      if (dialogOpenType.value === '添加') addRole()
      else setRole()

      dialogFormVisible.value = false
    } else {
      console.log('验证失败!')
    }
  })
}

onMounted(() => {
  initData()
})
</script>

<template>
  <div class="container">
    <div class="tools">
      <el-button @click="openDialogByInsert">添加角色</el-button>
    </div>

    <SytTable :columns="tableThs" :data="rolesTreeData">
      <template #operations="{ row }">
        <el-icon class="icon" color="#0af" @click="openDialogByEdit(row)"><Edit /></el-icon>
        <el-popconfirm title="确定删除?" @confirm="removeRole(row)">
          <template #reference>
            <el-icon class="icon" color="#f00"><Delete /></el-icon>
          </template>
        </el-popconfirm>
      </template>
    </SytTable>
    <el-dialog v-model="dialogFormVisible" :title="dialogOpenType" width="350px">
      <el-form
        ref="ruleFormRef"
        :model="dialogData"
        :rules="rules"
        size="large"
        class="w-full"
        label-width="auto"
      >
        <el-form-item label="角色名" prop="name">
          <el-input v-model="dialogData.name" placeholder="角色名" style="width: 240px" />
        </el-form-item>
        <el-form-item label="权限菜单" prop="menus">
          <el-tree-select
            v-model="dialogData.menus"
            :data="menusTreeData"
            :props="{ label: (data) => data.meta.title, value: 'id' }"
            check-strictly
            multiple
            :render-after-expand="false"
            style="width: 240px"
          />
        </el-form-item>
        <el-form-item label="上级角色">
          <el-tree-select
            v-model="dialogData.pid"
            :data="rolesTreeData"
            :props="{ label: 'name', value: 'id' }"
            check-strictly
            :render-after-expand="false"
            clearable
            style="width: 240px"
          />
        </el-form-item>
        <el-form-item>
          <el-button class="w-full" type="primary" @click="submitForm(ruleFormRef)">
            保存
          </el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>

<style scoped>
.container {
  width: 100%;
  height: 100%;
}

.tools {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 10px;
}

.tree {
  max-width: 600px;
  font-size: 16px;
  border: 1px solid #eef;
  padding: 10px;
  border-radius: 10px;
}

.icon {
  cursor: pointer;
  margin-left: 5px;
  font-size: 15px;
}
</style>
